package com.cubic.auth.service;

import com.alibaba.spring.util.WrapperUtils;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cubic.auth.core.AuthRequest;
import com.cubic.auth.entity.Client;
import com.cubic.auth.mapper.ClientMapper;
import com.cubic.auth.utils.JwtTokenUtil;
import com.cubic.govern.common.utils.DateUtils;
import com.cubic.govern.common.utils.jwt.JwtDetail;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.impl.DefaultClaims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * 用于服务间注册
 *
 * @ClassName UserServiceImpl
 * @Author QIANGLU
 * @Date 2020/11/18 2:25 下午
 * @Version 1.0
 */
@Slf4j
@Service
public class ClientServiceImpl implements ClientService {

    @Resource
    private ClientMapper clientMapper;


    /**
     * 获取token
     *
     * @param request
     * @return
     */
    @Override
    public String getToken(AuthRequest request) {

        try {

            String token = getCurrToken(request);

            if (StringUtils.isNotEmpty(token)) {
                return token;
            }

            //生成新token
            Claims claims = new DefaultClaims();
            claims.put("verCode", request.getVerCode());
            JwtDetail detail = JwtDetail.builder().exDate(new Date(System.currentTimeMillis() + JwtTokenUtil.getJwtProperties().getExpire())).id(request.getClientId()).claims(claims).build();

            String createToken = JwtTokenUtil.generateToken(detail);

            //更新存储
            insertRegister(request, createToken);

            return createToken;
        } catch (Exception e) {
            log.error("generateToken error", e);
        }

        return "";
    }

    @Override
    public String register(AuthRequest request) {

        if (request == null || StringUtils.isEmpty(request.getClientId())) {
            log.warn("register client is fail, request param is null or id is null");
            return "";
        }

        String token = getToken(request);

        return token;
    }

    /**
     * 没有就新增 有则刷新
     *
     * @param request
     * @param token
     */
    private void insertRegister(AuthRequest request, String token) {

        Client client = Client.builder().clientId(request.getClientId()).createTime(new Date()).token(token).build();

        Client c = clientMapper.selectByClientId(request.getClientId());

        if (c != null) {
            client.setId(c.getId());
            clientMapper.updateById(client);
            return;
        }

        clientMapper.insert(client);
    }

    /**
     * 线程内存和数据库进行token检索
     *
     * @param authRequest
     * @return
     */
    private String getCurrToken(AuthRequest authRequest) {

        if (authRequest == null || StringUtils.isEmpty(authRequest.getClientId())) {
            log.warn("get client token is fail, request param is null or id is null");
            return "";
        }

        Client client = clientMapper.selectByClientId(authRequest.getClientId());

        if (client == null || StringUtils.isEmpty(client.getToken())) {
            return "";
        }

        String token = client.getToken();

        JwtDetail detail = JwtTokenUtil.getInfoFromToken(token);

        if (detail != null && !detail.isExpired()) {
            return token;
        }
        log.info("未获取到 client :{} 有效token", authRequest.getClientId());
        return "";

    }


}
